<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Animation Border</title>
  <!-- Global -->
  <style>
    body {
      margin: 0 100px;
    }

    h1,
    h2,
    footer {
      text-align: center;
    }

    table {
      width: 100%;
    }

  </style>

  <!-- Box Model -->
  <style>
    .box_model {
      width: 200px;
      height: 100px;
      background: #cccccc;
      padding: 10px;
      border: 10px solid #409EFF;
      margin: 10px;
    }

    .border_box {
      box-sizing: border-box;
    }

  </style>

  <!-- Border -->
  <style>
    .default_box {
      width: 200px;
      height: 100px;
      margin: 10px;
    }

    .dotted {
      border: 10px #409EFF dotted;
    }

    .dashed {
      border: 10px #409EFF dashed;
    }

    .double {
      border: 10px #409EFF double;
    }

    .circle {
      width: 100px;
      border-radius: 60px;
      border: 10px #409EFF solid;
    }

    .circle_corner {
      width: 200px;
      border-radius: 25px;
      border: 5px #409EFF solid;
    }

    .partial_circle_corner {
      width: 200px;
      border-radius: 0 50px;
      border: 5px #409EFF solid;
    }

  </style>

  <!-- Animation -->

  <style>
    .animation_box {
      background: gold;
      width: 200px;
      height: 100px;
      transition: transform 2s;
    }

    .rotate_box:hover {
      transform: rotateZ(90deg);
    }

    .scale_box:hover {
      transform: scale(0.5);
    }

    .translate_box:hover {
      transform: translate(100px, 0);
    }

    .transition_box {
      transition: width 2s;
    }

    .transition_box:hover {
      width: 400px;
    }

    .ani_box {
      background: gold;
      width: 200px;
      height: 100px;
      animation: change-len 2s infinite linear;
    }

    @keyframes change-len {

      0%,
      50%,
      100% {
        width: 200px;
      }

      25% {
        width: 100px;
      }

      75% {
        width: 300px;
      }
    }

  </style>

  <!-- Animation: change_length -->
  <style>
    .change_length {
      width: 200px;
      height: 100px;
      color: #03a9f3;
      position: relative;
      line-height: 100px;
      text-align: center;
      border: 5px solid #03A9F3;
    }

    .change_length::before,
    .change_length::after {
      content: "";
      position: absolute;
      width: 20px;
      height: 10px;
      transition: width 1s, height 1s;
    }

    .change_length::before {
      top: -15px;
      left: -15px;
      border-top: 5px solid #03A9F3;
      border-left: 5px solid #03A9F3;
    }

    .change_length::after {
      bottom: -15px;
      right: -15px;
      border-bottom: 5px solid #03A9F3;
      border-right: 5px solid #03A9F3;
    }

    .change_length:hover::before,
    .change_length:hover::after {
      width: calc(100% + 25px);
      height: calc(100% + 25px);
    }

    .transform_box {
      position: relative;
      width: 200px;
      height: 100px;
      line-height: 100px;
      text-align: center;
      overflow: hidden;
    }

    .transform_box::after {
      content: "Hover Me";
      position: absolute;
      top: 4px;
      bottom: 4px;
      right: 4px;
      left: 4px;
      line-height: 92px;
      font-size: 24px;
      background: #fff;
      border: 2px solid yellowgreen;
      color: yellowgreen;
    }

    .transform_box::before {
      content: "";
      position: absolute;
      top: 0px;
      bottom: 0px;
      right: -20px;
      left: 0px;
      background: yellowgreen;
      transform: rotateZ(-90deg) translate(-100%, -100%);
      transform-origin: top left;
      transition: transform .5s;
      transition-timing-function: linear;
    }

    .transform_box:hover::before {
      transform: rotateZ(0deg) translate(0%, -0%);
    }

  </style>

  <!-- Animation: running -->
  <style>
    .running {
      width: 200px;
      height: 100px;
      line-height: 100px;
      text-align: center;
      color: #F56C6C;
      outline: 5px solid #F56C6C;
      outline-offset: -5px;
      background:
        /* 上 */
        linear-gradient(90deg, #F56C6C 50%, transparent 50%) repeat-x,
        /* 右 */
        linear-gradient(180deg, #F56C6C 50%, transparent 50%) repeat-y,
        /* 下 */
        linear-gradient(90deg, #F56C6C 50%, transparent 50%) repeat-x,
        /* 左 */
        linear-gradient(180deg, #F56C6C 50%, transparent 50%) repeat-y;
      background-size: 20px 5px, 5px 20px, 20px 5px, 5px 20px;
      background-position: 0 0, 100% 0, 0 100%, 0 0;
    }

    .running:hover {
      outline: 0;
      animation: position-move .3s infinite linear;
    }

    @keyframes position-move {

      /* 顺时针 */
      100% {
        background-position: 20px 0, 100% 20px, -20px 100%, 0 -20px;
      }
    }

  </style>

  <!-- Animation: rotating_color -->
  <style>
    .rotating_color {
      width: 200px;
      height: 200px;
      position: relative;
      overflow: hidden;
    }

    .rotating_color::before {
      content: "Hello World!";
      position: absolute;
      left: 5px;
      top: 5px;
      width: calc(100% - 10px);
      height: calc(100% - 10px);
      line-height: 190px;
      text-align: center;
      background: white;
      z-index: 1;
    }

    .rotating_color::after {
      content: "";
      position: absolute;
      left: -50%;
      top: -50%;
      width: 200%;
      height: 200%;
      background-repeat: no-repeat;
      background-size: 50% 50%;
      background-position: 0 0, 100% 0, 100% 100%, 0 100%;
      background-image:
        linear-gradient(#399953, #399953),
        linear-gradient(#fbb300, #fbb300),
        linear-gradient(#d53e33, #d53e33),
        linear-gradient(#377af5, #377af5);
      animation: box-rotate 4s infinite linear;
    }

    @keyframes box-rotate {
      100% {
        transform: rotate(1turn);
      }
    }

  </style>

  <!-- Animation: wandering -->
  <style>
    .wandering {
      width: 200px;
      height: 200px;
      position: relative;
      overflow: hidden;
      border: 1px dotted #C0C4CC;
    }

    .wandering::before {
      content: "Happy New Year";
      position: absolute;
      left: 5px;
      top: 5px;
      width: calc(100% - 10px);
      height: calc(100% - 10px);
      line-height: 190px;
      text-align: center;
      background: white;
      z-index: 1;
    }

    .wandering::after {
      content: "";
      position: absolute;
      left: -50%;
      top: -50%;
      width: 200%;
      height: 200%;
      background-repeat: no-repeat;
      background-size: 50% 50%;
      background-position: 0 0;
      background-image:
        linear-gradient(black, #909399);
      animation: box-rotate 4s infinite linear;
    }

    @keyframes box-rotate {
      100% {
        transform: rotate(1turn);
      }
    }

  </style>
  <!-- Animation: scanning -->
  <style>
    .scanning {
      position: relative;
      z-index: 0;
      width: 400px;
      height: 300px;
      margin: 20px;
      border-radius: 10px;
      overflow: hidden;
      padding: 2rem;

    }

    .scanning::before {
      content: '';
      position: absolute;
      z-index: -2;
      left: -50%;
      top: -50%;
      width: 200%;
      height: 200%;
      background-color: #1a232a;
      background-repeat: no-repeat;
      background-position: 0 0;
      background-image: conic-gradient(transparent, rgba(168, 239, 255, 1), transparent 30%);
      animation: box-rotate 4s linear infinite;
    }

    .scanning::after {
      content: '';
      position: absolute;
      z-index: -1;
      left: 6px;
      top: 6px;
      width: calc(100% - 12px);
      height: calc(100% - 12px);
      background: #000;
      border-radius: 5px;
      animation: opacityChange 6s infinite linear;
    }

    @keyframes opacityChange {
      50% {
        opacity: .5;
      }

      100% {
        opacity: 1;
      }
    }

    @keyframes box-rotate {
      100% {
        transform: rotate(1turn);
      }
    }

  </style>

  <!-- Animation: surrounding -->
  <style>
    .surrounding {
      position: relative;
      width: 400px;
      height: 200px;
      border-radius: 50px;
      line-height: 200px;
      text-align: center;
      font-size: 30px;
    }

    .surrounding::before,
    .surrounding::after {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      border: 5px solid gold;
      animation: clippath 3s infinite linear;
      border-radius: 50px;
    }

    .surrounding::after {
      animation: clippath 3s infinite -1.5s linear;
    }

    @keyframes clippath {

      0%,
      100% {
        clip-path: inset(0 0 95% 0);
      }

      25% {
        clip-path: inset(0 95% 0 0);
      }

      50% {
        clip-path: inset(95% 0 0 0);
      }

      75% {
        clip-path: inset(0 0 0 95%);
      }
    }

  </style>
</head>

<body>
  <h1>CSS 动画的应用 —— 边框</h1>

  <h2>盒模型 | Box Model</h2>

  <p>
    盒模型是指对一个文档进行布局时，浏览器的渲染引擎将所有元素表示为一个矩形的盒子。
    每个盒子由四部分组成，从内到外依次是内容（content）、内边距（padding）、边框（border）、外边距（margin）。
  </p>

  <p>这是一个宽 200px ，高 100px 的 div， padding、border、margin均为 10px</p>
  <div class="box_model"></div>

  <p>
    NOTE: CSS3 中对于盒子规定了两种类型：内容盒（content-box）和边框盒（border-box）
  </p>

  <table border="1">
    <tbody>
      <tr>
        <th style="width:25%;">值</th>
        <th>描述</th>
      </tr>

      <tr>
        <td>content-box</td>
        <td>
          <p>这是由 CSS2.1 规定的宽度高度行为。</p>
          <p>宽度和高度分别应用到元素的内容框。</p>
          <p>在宽度和高度之外绘制元素的内边距和边框。</p>
        </td>
      </tr>

      <tr>
        <td>border-box</td>
        <td>
          <p>为元素设定的宽度和高度决定了元素的边框盒。</p>
          <p>就是说，为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。</p>
          <p>通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。</p>
        </td>
      </tr>

      <tr>
        <td>inherit</td>
        <td>规定应从父元素继承 box-sizing 属性的值。</td>
      </tr>
    </tbody>
  </table>

  <p>设置了 box-sizing: content-box</p>
  <div class="box_model"></div>
  <p>设置了 box-sizing: border-box</p>
  <div class="box_model border_box"></div>

  <h2>边框 | Border</h2>

  <p>border 一共有三类属性设置，分别是 border-style、border-width、border-color</p>

  <table border="1">
    <tbody>
      <tr>
        <th style="width:25%;">属性</th>
        <th>描述</th>
      </tr>

      <tr>
        <td>border-style</td>
        <td>
          <p>用于设置元素所有边框的样式，或者单独地为各边设置边框样式。</p>
          <p>可能的值： none、dotted、dashed、solid、double、groove、ridge、inset、outset</p>
        </td>
      </tr>

      <tr>
        <td>border-width</td>
        <td>
          <p>用于为元素的所有边框设置宽度，或者单独地为各边边框设置宽度。</p>
        </td>
      </tr>

      <tr>
        <td>border-color</td>
        <td>设置元素的所有边框中可见部分的颜色，或为 4 个边分别设置颜色。</td>
      </tr>
    </tbody>
  </table>

  <div class="default_box dotted"></div>
  <div class="default_box dashed"></div>
  <div class="default_box double"></div>

  <p>border-radius 可以设置边框圆角，经常被用来绘制一个圆。</p>

  <div class="default_box circle"></div>
  <div class="default_box circle_corner"></div>
  <div class="default_box partial_circle_corner"></div>

  <h2>动画 | Animation </h2>

  <table border="1">
    <tbody>
      <tr>
        <th style="width:25%;">属性</th>
        <th>描述</th>
      </tr>

      <tr>
        <td>transform</td>
        <td>
          <p>对元素进行移动、缩放、转动、拉长或拉伸。</p>
          <p>可以使用的函数： translate()
            rotate()
            scale()
            skew()
            matrix()</p>
        </td>
      </tr>

      <tr>
        <td>transition</td>
        <td>
          <p>过渡是元素从一种样式逐渐改变为另一种的效果。</p>
          <p>1. 规定您希望把效果添加到哪个 CSS 属性上；2. 规定效果的时长。</p>
        </td>
      </tr>

      <tr>
        <td>animation</td>
        <td>
          <p> 动画是使元素从一种样式逐渐变化为另一种样式的效果。并且可以改变任意多的样式任意多的次数。 </p>
          <p>0% 是动画的开始，100% 是动画的完成。"from" 和 "to"，等同于 0% 和 100% 。</p>
        </td>
      </tr>
    </tbody>
  </table>

  <h3>transform -- translate</h3>

  <div class="animation_box translate_box"></div>

  <h3>transform -- scale</h3>

  <div class="animation_box scale_box"></div>

  <h3>transform -- rotate</h3>

  <div class="animation_box rotate_box"></div>

  <h3>transition</h3>

  <div class="animation_box transition_box"></div>

  <h3>animation</h3>

  <div class="ani_box"></div>

  <h2>实战 | Examples</h2>

  <h3>变长</h3>

  <div class="change_length">Hover Me!</div>

  <h3>渐满</h3>

  <div class="transform_box"></div>

  <h3>运动</h3>

  <div class="running">Hover Me!</div>

  <h3>旋转</h3>

  <!-- 缺陷：对长宽比有要求，这里用正方形演示 -->
  <div class="rotating_color"></div>

  <h3>游走</h3>

  <div class="wandering"></div>

  <!-- 这个涉及到圆锥渐变，暂不讲 -->
  <!-- <h3>扫描</h3>

  <div class="scanning"></div> -->

  <h3>环绕</h3>

  <div class="surrounding">春节快乐，牛气冲天!</div>

  <h2>参考 | References</h2>

  <ol>
    <li>
      <a href="https://www.cnblogs.com/coco1s/p/14291567.html">CSS 奇思妙想边框动画</a>
    </li>
    <li>
      <a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model">CSS
        基础盒模型</a>
    </li>
    <li>
      <a href="https://www.cnblogs.com/EnSnail/p/9771973.html">CSS 的 conic-gradient 学习</a>
    </li>
    <li>
      <a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/basic-shape">clip-path basic-shape MDN</a>
    </li>
  </ol>

  <footer>made by zhu peng ji 2021-02-08</footer>
</body>

</html>
